package documents

import (
	doc "beergo/lib/base/document"
	"beergo/lib/event"
	mgo "beergo/lib/mongo"
	"beergo/lib/tool"
	"github.com/beego/beego/v2/server/web/context"
	ctx "context"
	"go.mongodb.org/mongo-driver/bson"
	"go.mongodb.org/mongo-driver/bson/primitive"
	"go.mongodb.org/mongo-driver/mongo"
	"reflect"
)

func (doc *ErrorLog) DocName() string             { return "ErrorLog" }

func (doc *ErrorLog) GetId() primitive.ObjectID   { return doc.Id }

func (doc *ErrorLog) SetId(id primitive.ObjectID) { doc.Id = id }

func (this *ErrorLog) GetReflect() reflect.Type {
return reflect.TypeOf(ErrorLog{})
}

func (this ErrorLog) New() *ErrorLog {
	model := new(ErrorLog)
	if !this.GetEventBusOff() {
	    event.DispatchToMany("ErrorLogNew", model, &context.Context{})
	}
	return model
}

func (this *ErrorLog) Delete() error {
	_,err := doc.GetMgo().DeleteOne(ctx.TODO(), this)
	return err
}
func (this *ErrorLog) Save(kvs ...map[string]interface{}) error {
	if this.Id.IsZero() {
		if !this.GetEventBusOff() {
		    event.DispatchToMany("BeforeErrorLogCreate", this, &context.Context{})
		}
		err := doc.GetMgo().InsertOne(ctx.TODO(), this)
		if err != nil {
			return err
		}
		if !this.GetEventBusOff() {
		    event.DispatchToMany("AfterErrorLogCreate", this, &context.Context{})
		}
	} else {
		if !this.GetEventBusOff() {
		    event.DispatchToMany("BeforeErrorLogUpdate", this, &context.Context{})
		}
		update := make(bson.D, 0)
		if len(kvs)==0 {
			for index, value := range this.ToArray() {
				if index == "id" {
					continue
				}
				update = append(update, bson.E{index, value})
			}
		}else {
			for _, kv := range kvs {
				for index, value := range kv {
					if index == "id" {
						continue
					}
					update = append(update, bson.E{index, value})
				}
			}
		}
		_, err := doc.GetStore(this.DocName()).UpdateOne(ctx.TODO(), tool.M{"_id": this.Id}, bson.M{"$set": update})
		if err != nil {
			return err
		}
		if !this.GetEventBusOff() {
		    event.DispatchToMany("AfterErrorLogUpdate", this, &context.Context{})
		}
	}
	return nil
}

func (this *ErrorLog) ToArray() map[string]interface{} {
	data := tool.StringKeyMap{}
	data["id"] = this.Id
	data["file"] = this.File
	data["line"] = this.Line
	data["error"] = this.Error
	return data
}

/***************************************
			Repository
****************************************/
type ErrorLogRepository struct {}

func (this *ErrorLogRepository) GetQuerySetter() *mongo.Collection {
	m := new(ErrorLog)
	return doc.GetStore(m.DocName())
}

func (rep ErrorLogRepository) Find(id string) ErrorLog {
	filter := tool.DbCreateFilter()
	filter["_id"],_ = primitive.ObjectIDFromHex(id)
	return rep.FindOneBy(filter, nil)
}

func (rep ErrorLogRepository) FindOneBy(filters map[string]interface{}, orderbys []string) ErrorLog {
	model := ErrorLog{}
	qs := rep.GetQuerySetter()
	rst := qs.FindOne(ctx.TODO(), doc.CreateFilter(filters), doc.CreateFindOneOption(orderbys))
	err := rst.Decode(&model)
	if err != nil {}
	return model
}

func (rep ErrorLogRepository) FindBy(filters map[string]interface{}, orderbys []string, limit int, offset int) []ErrorLog {
	var re []ErrorLog
	qs := rep.GetQuerySetter()
	rst, err := qs.Find(ctx.TODO(), doc.CreateFilter(filters), doc.CreateOption(orderbys, offset, limit))
	if err != nil {return re}
	errd := rst.All(ctx.TODO(), &re)
	if errd != nil {return re}
	return re
}

func (rep ErrorLogRepository) FindAll(orderbys []string) []ErrorLog {
	var re []ErrorLog
	qs := rep.GetQuerySetter()
	rst, err := qs.Find(ctx.TODO(), doc.CreateFilter(nil), doc.CreateOption(orderbys, 0, 0))
	if err != nil {return re}
	errd := rst.All(ctx.TODO(), &re)
	if errd != nil {return re}
	return re
}

func (rep ErrorLogRepository) GetList(builder *mgo.QueryBuilder) ([]*ErrorLog, error) {
	var re []*ErrorLog
	qs := rep.GetQuerySetter()
	rst, err := qs.Find(ctx.TODO(),
		doc.CreateFilter(builder.GetFilter()),
		doc.CreateOption(builder.GetOrder(), builder.GetOffset(), builder.GetLimit()))
	if err != nil {return nil, err}
	errd := rst.All(ctx.TODO(), &re)
	if errd != nil {return nil, err}
	//计数
	count,_:=qs.CountDocuments(ctx.TODO(),
		doc.CreateFilter(builder.GetFilter()),nil)
	builder.Total = count
	return re, nil
}